package co.edu.jerojasol.service;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import co.edu.jerojasol.entities.Marcador;
import co.edu.jerojasol.entities.Partido;
import co.edu.jerojasol.entities.PosicionEquipo;
import co.edu.jerojasol.entities.PosicionUsuario;
import co.edu.jerojasol.entities.Usuario;
import co.edu.jerojasol.persistence.MarcadorDAO;
import co.edu.jerojasol.persistence.PartidoDAO;
import co.edu.jerojasol.persistence.UsuarioDAO;

@Service("UsuarioService")
@Transactional(readOnly = true)
public class UsuarioService {

	@Autowired
	UsuarioDAO usuarioDAO;
	
	@Autowired
	PartidoDAO partidoDAO;
	
	@Autowired
	MarcadorDAO marcadorDAO;
	
	Map<Integer, Integer> puntosPorFase;

	@PostConstruct
	public void init(){
		inicializarPuntos();
	}
	
	public UsuarioDAO getUsuarioDAO() {
		return usuarioDAO;
	}

	public void setUsuarioDAO(UsuarioDAO usuarioDAO) {
		this.usuarioDAO = usuarioDAO;
	}
	
	public PartidoDAO getPartidoDAO() {
		return partidoDAO;
	}

	public void setPartidoDAO(PartidoDAO partidoDAO) {
		this.partidoDAO = partidoDAO;
	}

	public MarcadorDAO getMarcadorDAO() {
		return marcadorDAO;
	}

	public void setMarcadorDAO(MarcadorDAO marcadorDAO) {
		this.marcadorDAO = marcadorDAO;
	}
	
	public Map<Integer, Integer> getPuntosPorFase() {
		return puntosPorFase;
	}

	public void setPuntosPorFase(Map<Integer, Integer> puntosPorFase) {
		this.puntosPorFase = puntosPorFase;
	}

	public List<Usuario> getUsuarios(){
		return usuarioDAO.getUsuarios();
	}
	
	public Usuario createUser(String nombres, String apellidos, String habilitado, String login, String password, String identificacion, String correo) throws NoSuchAlgorithmException{
		
		Usuario usuario = new Usuario();
		usuario.setNombres(nombres);
		usuario.setApellidos(apellidos);
		usuario.setHabilitado(habilitado);
		usuario.setLogin(login);
		usuario.setPassword(obtenerMD5(password));
		usuario.setIdusuario(Integer.parseInt(identificacion));
		usuario.setCorreo(correo);
		
		usuario = usuarioDAO.createUser(usuario);
		
		if (usuario != null){
			List<Partido> partidos = partidoDAO.getPartidos();
			
			for (Partido partido : partidos){
				Marcador marcador = new Marcador();
				marcador.setFechaModificacion(new Date());
				marcador.setIdpartido(partido);
				marcador.setIdusuario(usuario);
				marcadorDAO.createMarcador(marcador);
			}
		}
		
		return usuario;
	}
	
	public Usuario actualizarUsuario(Usuario usuario){
		return usuarioDAO.actualizarUsuario(usuario);
	}
	
	public Usuario consultarUsuarioPorLoginYPassword(String login, String password) throws NoSuchAlgorithmException{
		
		Usuario resultado = usuarioDAO.consultarUsuarioPorLoginYPassword(login, obtenerMD5(password));
		
		if (resultado != null){
			System.out.println("Se encontro usuario "+resultado.getNombres()+" "+resultado.getApellidos());
		}else{
			System.out.println("No se encontro usuario");
		}
	
		return resultado;
	}
	
	public String obtenerMD5(String cadena) throws NoSuchAlgorithmException{
		MessageDigest mdEnc = MessageDigest.getInstance("MD5"); 
		mdEnc.update(cadena.getBytes(), 0, cadena.length());
		String md5 = new BigInteger(1, mdEnc.digest()).toString(16);
		return md5;
	}
	
	public List<PosicionUsuario> obtenerPosicionUsuarios(){
		
		List<PosicionUsuario> listaResultado = new ArrayList<PosicionUsuario>();
		
		List<Usuario> usuarios = usuarioDAO.getUsuarios();
		
		for (Usuario usuario: usuarios){
			
			PosicionUsuario posicionUsuario = new PosicionUsuario(usuario);
			
			List<Marcador> marcadoresUsuario = marcadorDAO.consultarMarcadoresCerradosPorUsuario(usuario.getIdusuario());
			
			for (Marcador marcador: marcadoresUsuario){
				System.out.println("Marcador del usuario "+usuario.getIdusuario());
				
				Partido partido = marcador.getIdpartido();
				
				if (partido.getEstado().equals("C")){
					System.out.println( "para el partido "+partido.getIdpartido()+" con fase"+partido.getIdfase().getIdfase());
					
					int puntosARecibir = 0;
					
					int marcadorUno =marcador.getMarcadorUno();
					int marcadorDos = marcador.getMarcadorDos();
					int resultadoUno = partido.getResultadoUno();
					int resultadoDos = partido.getResultadoDos();
					
					if (marcadorUno == resultadoUno && marcadorDos == resultadoDos){
						puntosARecibir = (Integer)puntosPorFase.get(partido.getIdfase().getIdfase());
					}else if ((marcadorUno > marcadorDos && resultadoUno > resultadoDos) || (marcadorUno < marcadorDos && resultadoUno < resultadoDos) ||(marcadorUno == marcadorDos && resultadoUno == resultadoDos)){
						puntosARecibir = 2;
					}else if (marcadorUno == resultadoUno || marcadorDos == resultadoDos){
						puntosARecibir = 1;
					}
					
					if (partido.getIdfase().getIdfase().intValue() < 9){
						posicionUsuario.setPrimeraFase(posicionUsuario.getPrimeraFase()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}else if (partido.getIdfase().getIdfase().intValue() == 9){
						posicionUsuario.setOctavos(posicionUsuario.getOctavos()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}else if (partido.getIdfase().getIdfase().intValue() == 10){
						posicionUsuario.setCuartos(posicionUsuario.getCuartos()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}else if (partido.getIdfase().getIdfase().intValue() == 11){
						posicionUsuario.setSemifinales(posicionUsuario.getSemifinales()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}else if (partido.getIdfase().getIdfase().intValue() == 12){
						posicionUsuario.setTerceroCuarto(posicionUsuario.getTerceroCuarto()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}else if (partido.getIdfase().getIdfase().intValue() == 13){
						posicionUsuario.setPuntosFinal(posicionUsuario.getPuntosFinal()+puntosARecibir);
						posicionUsuario.setPuntosTotal(posicionUsuario.getPuntosTotal()+puntosARecibir);
					}
				}
				
			}
			listaResultado.add(posicionUsuario);
		}
		ordenarUsuarios(listaResultado);
		
		return listaResultado;
	}
	
	public void ordenarUsuarios(List<PosicionUsuario> usuarios) {

		for (int i = 0; i < usuarios.size() - 1; i++) {
			for (int j = i+1; j < usuarios.size(); j++) {

				PosicionUsuario usuario1 = usuarios.get(i);
				PosicionUsuario usuario2 = usuarios.get(j);

				if (usuario1.getPuntosTotal() < usuario2.getPuntosTotal()) {
					PosicionUsuario usuarioTmp = usuario1;
					usuarios.set(i, usuario2);
					usuarios.set(j, usuarioTmp);
				} 
			}
		}

	}
	
	public void inicializarPuntos(){
		puntosPorFase = new HashMap<Integer, Integer>();
		
		puntosPorFase.put(new Integer(1),new Integer(3));
		puntosPorFase.put(new Integer(2),new Integer(3));
		puntosPorFase.put(new Integer(3),new Integer(3));
		puntosPorFase.put(new Integer(4),new Integer(3));
		puntosPorFase.put(new Integer(5),new Integer(3));
		puntosPorFase.put(new Integer(6),new Integer(3));
		puntosPorFase.put(new Integer(7),new Integer(3));
		puntosPorFase.put(new Integer(8),new Integer(3));
		puntosPorFase.put(new Integer(9),new Integer(4));
		puntosPorFase.put(new Integer(10),new Integer(5));
		puntosPorFase.put(new Integer(11),new Integer(6));
		puntosPorFase.put(new Integer(12),new Integer(7));
		puntosPorFase.put(new Integer(13),new Integer(8));
		
	}
	
}
